package com.ksm.client.document.view;

import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Singleton;
import com.ksm.client.document.TvaProperties;
import com.ksm.client.document.TypeDocumentProperties;
import com.ksm.client.document.presenter.DocumentFormPresenter.IDocumentFormView;
import com.ksm.client.document.presenter.IDocumentFormPresenter;
import com.ksm.transfer.dto.TvaDTO;
import com.ksm.transfer.dto.TypeDocumentDTO;
import com.sencha.gxt.data.shared.LabelProvider;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.Component;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.event.ParseErrorEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.form.ComboBox;
import com.sencha.gxt.widget.core.client.form.DateField;
import com.sencha.gxt.widget.core.client.form.FormPanel;
import com.sencha.gxt.widget.core.client.form.NumberField;
import com.sencha.gxt.widget.core.client.form.NumberPropertyEditor;
import com.sencha.gxt.widget.core.client.form.NumberPropertyEditor.LongPropertyEditor;
import com.sencha.gxt.widget.core.client.form.TextArea;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.form.validator.MinDateValidator;
import com.sencha.gxt.widget.core.client.info.Info;

@Singleton
public class DocumentFormView extends ResizeComposite implements IsWidget, IDocumentFormView {

	private IDocumentFormPresenter presenter;

	interface MyUiBinder extends UiBinder<Component, DocumentFormView> {
	}

	private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

	private Component vp;

	TypeDocumentProperties typeProperties = GWT.<TypeDocumentProperties> create(TypeDocumentProperties.class);
	@UiField(provided = true)
	ListStore<TypeDocumentDTO> typeStore = new ListStore<TypeDocumentDTO>(typeProperties.key());
	@UiField(provided = true)
	ComboBox<TypeDocumentDTO> comboType = new ComboBox<TypeDocumentDTO>(typeStore, typeProperties.nameLabel());

	TvaProperties tvaProperties = GWT.create(TvaProperties.class);
	@UiField(provided = true)
	ListStore<TvaDTO> tvaStore = new ListStore<TvaDTO>(tvaProperties.key());
	@UiField(provided = true)
	ComboBox<TvaDTO> comboTVA = new ComboBox<TvaDTO>(tvaStore, tvaProperties.nameLabel());

	@UiField
	DateField date;

	@UiField(provided = true)
	final FormPanel form = new FormPanel();

	@UiField(provided = true)
	NumberPropertyEditor<Long> longPropertyEditor = new LongPropertyEditor();

	Long idDocument = null;

	@UiField
	TextField interlocuteur;

	@UiField
	TextArea commentaire;

	@UiField
	TextButton validButton;

	@UiField(provided = true)
	NumberField<Double> montant;

	@Override
	public Widget asWidget() {
		if (vp == null) {

			montant = new NumberField<Double>(new NumberPropertyEditor.DoublePropertyEditor());

			vp = uiBinder.createAndBindUi(this);
			// initComboType(TestData.getSomeStocks());
			// initComboTva(TestData.getSomeTVA());
			date.addValidator(new MinDateValidator(new Date()));
		}

		return vp;
	}

	@Override
	public void initComboType(List<TypeDocumentDTO> elements) {
		typeStore.addAll(elements);
		comboType.setValue(elements.get(0));
		addHandlersForEventObservation(comboType, typeProperties.nameLabel());
	}

	@Override
	public void initComboTva(List<TvaDTO> elements) {
		tvaStore.addAll(elements);
		comboTVA.setValue(elements.get(0));
	}

	@UiHandler("commentaire")
	public void firstNameChanged(ValueChangeEvent<String> event) {
		Info.display("Value Changed", "First name changed to " + event.getValue() == null ? "blank" : event.getValue());
	}

	@UiHandler("interlocuteur")
	public void interlocuteurChanged(ValueChangeEvent<String> event) {
		Info.display("Value Changed", "First name changed to " + event.getValue() == null ? "blank" : event.getValue());
	}

	@UiHandler("montant")
	public void onAgeParseError(ParseErrorEvent event) {
		Info.display("Parse Error", event.getErrorValue() + " could not be parsed as a number");
	}

	@UiHandler("date")
	public void onDateParseError(ParseErrorEvent event) {
		Info.display("Parse Error", event.getErrorValue() + " could not be parsed as a date");
	}

	@UiHandler("date")
	public void onDateChanged(ValueChangeEvent<Date> event) {
		String v = event.getValue() == null ? "nothing" : DateTimeFormat.getFormat(PredefinedFormat.DATE_MEDIUM).format(event.getValue());
		Info.display("Selected", "You selected " + v);
	}

	@UiHandler("validButton")
	public void onValidate(SelectEvent evt) {
		presenter.saveDocument();
	}

	@UiHandler("resetButton")
	public void onReset(SelectEvent evt) {
		resetForm();
	}

	public void resetForm() {
		form.reset();
		idDocument = null;
	}

	private <T> void addHandlersForEventObservation(ComboBox<T> combo, final LabelProvider<T> labelProvider) {
		combo.addValueChangeHandler(new ValueChangeHandler<T>() {

			@Override
			public void onValueChange(ValueChangeEvent<T> event) {
				Info.display("Value Changed", "New value: " + (event.getValue() == null ? "nothing" : labelProvider.getLabel(event.getValue()) + "!"));
			}
		});
		combo.addSelectionHandler(new SelectionHandler<T>() {

			@Override
			public void onSelection(SelectionEvent<T> event) {
				Info.display("State Selected", "You selected " + (event.getSelectedItem() == null ? "nothing" : labelProvider.getLabel(event.getSelectedItem()) + "!"));
			}
		});
	}

	@Override
	public IDocumentFormPresenter getPresenter() {
		return presenter;
	}

	@Override
	public void setPresenter(IDocumentFormPresenter presenter) {
		this.presenter = presenter;
	}

	@Override
	public DateField getDate() {
		return date;
	}

	@Override
	public void setDate(DateField date) {
		this.date = date;
	}

	@Override
	public NumberField<Double> getMontant() {
		return montant;
	}

	@Override
	public void setMontant(NumberField<Double> montant) {
		this.montant = montant;
	}

	@Override
	public TextField getInterlocuteur() {
		return interlocuteur;
	}

	@Override
	public void setInterlocuteur(TextField interlocuteur) {
		this.interlocuteur = interlocuteur;
	}

	@Override
	public TextArea getCommentaire() {
		return commentaire;
	}

	@Override
	public void setCommentaire(TextArea commentaire) {
		this.commentaire = commentaire;
	}

	// @Override
	// public NumberField<Long> getId() {
	// return id;
	// }
	//
	// @Override
	// public void setId(NumberField<Long> id) {
	// this.id = id;
	// }

	@Override
	public ComboBox<TypeDocumentDTO> getComboType() {
		return comboType;
	}

	@Override
	public void setComboType(ComboBox<TypeDocumentDTO> comboType) {
		this.comboType = comboType;
	}

	@Override
	public ComboBox<TvaDTO> getComboTVA() {
		return comboTVA;
	}

	@Override
	public void setComboTVA(ComboBox<TvaDTO> comboTVA) {
		this.comboTVA = comboTVA;
	}

	public Long getIdDocument() {
		return idDocument;
	}

	public void setIdDocument(Long idDocument) {
		this.idDocument = idDocument;
	}

	@Override
	public void setTva(Long tvaId) {
		if (tvaStore != null && tvaId != null) {
			for (TvaDTO tva : tvaStore.getAll()) {
				if (tva.getId().equals(tvaId)) {
					comboTVA.setValue(tva);
				}
			}
		}
	}

	@Override
	public void setType(Long typeId) {
		if (typeStore != null && typeId != null) {
			for (TypeDocumentDTO type : typeStore.getAll()) {
				if (type.getId().equals(typeId)) {
					comboType.setValue(type);
				}
			}
		}

	}
}